#include "logger.hpp"
#include <sys/stat.h>
#include <sys/types.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <ctime>

MyLogger::MyLogger() 
    : logDirectory_("./logs")
    , currentDate_("") {
    // 创建日志目录
    mkdir(logDirectory_.c_str(), 0755);
}

MyLogger::~MyLogger() {
    if (serverLogFile_.is_open()) {
        serverLogFile_.close();
    }
    if (dbLogFile_.is_open()) {
        dbLogFile_.close();
    }
}

MyLogger& MyLogger::getInstance() {
    static MyLogger instance;
    return instance;
}

void MyLogger::setLogDirectory(const std::string& dir) {
    logDirectory_ = dir;
    // 创建日志目录(如果不存在)
    mkdir(logDirectory_.c_str(), 0755);
}

std::string MyLogger::getCurrentDate() {
    time_t now = time(nullptr);
    struct tm* timeinfo = localtime(&now);
    
    std::ostringstream oss;
    oss << std::setfill('0') 
        << std::setw(4) << (timeinfo->tm_year + 1900) << "-"
        << std::setw(2) << (timeinfo->tm_mon + 1) << "-"
        << std::setw(2) << timeinfo->tm_mday;
    
    return oss.str();
}

std::string MyLogger::getCurrentDateTime() {
    time_t now = time(nullptr);
    struct tm* timeinfo = localtime(&now);
    
    std::ostringstream oss;
    oss << std::setfill('0')
        << std::setw(4) << (timeinfo->tm_year + 1900) << "-"
        << std::setw(2) << (timeinfo->tm_mon + 1) << "-"
        << std::setw(2) << timeinfo->tm_mday << " "
        << std::setw(2) << timeinfo->tm_hour << ":"
        << std::setw(2) << timeinfo->tm_min;
    
    return oss.str();
}

std::string MyLogger::getLevelString(LogLevel level) {
    switch (level) {
        case LogLevel::INFO:  return "INFO";
        case LogLevel::WARN:  return "WARN";
        case LogLevel::ERROR: return "ERROR";
        default: return "UNKNOWN";
    }
}

std::string MyLogger::getLogFilePath(LogType type, const std::string& date) {
    std::string filename;
    if (type == LogType::SERVER) {
        filename = "server_" + date + ".log";
    } else {
        filename = "database_" + date + ".log";
    }
    return logDirectory_ + "/" + filename;
}

void MyLogger::checkAndRotateLogFile(LogType type) {
    std::string today = getCurrentDate();
    
    // 如果日期变化,需要关闭旧文件,打开新文件
    if (currentDate_ != today) {
        currentDate_ = today;
        
        // 关闭旧的日志文件
        if (type == LogType::SERVER && serverLogFile_.is_open()) {
            serverLogFile_.close();
        }
        if (type == LogType::DATABASE && dbLogFile_.is_open()) {
            dbLogFile_.close();
        }
    }
    
    // 打开或创建当天的日志文件
    if (type == LogType::SERVER && !serverLogFile_.is_open()) {
        std::string filepath = getLogFilePath(LogType::SERVER, currentDate_);
        serverLogFile_.open(filepath, std::ios::app);
        if (!serverLogFile_.is_open()) {
            std::cerr << "Failed to open server log file: " << filepath << std::endl;
        }
    } else if (type == LogType::DATABASE && !dbLogFile_.is_open()) {
        std::string filepath = getLogFilePath(LogType::DATABASE, currentDate_);
        dbLogFile_.open(filepath, std::ios::app);
        if (!dbLogFile_.is_open()) {
            std::cerr << "Failed to open database log file: " << filepath << std::endl;
        }
    }
}

void MyLogger::writeLog(LogType type, LogLevel level, const std::string& message) {
    // 根据日志类型选择对应的锁和文件流
    if (type == LogType::SERVER) {
        std::lock_guard<std::mutex> lock(serverMutex_);
        checkAndRotateLogFile(LogType::SERVER);
        
        if (serverLogFile_.is_open()) {
            serverLogFile_ << "[" << getCurrentDateTime() << "] "
                          << "[" << getLevelString(level) << "] "
                          << message << std::endl;
            serverLogFile_.flush();
        }
    } else if (type == LogType::DATABASE) {
        std::lock_guard<std::mutex> lock(dbMutex_);
        checkAndRotateLogFile(LogType::DATABASE);
        
        if (dbLogFile_.is_open()) {
            dbLogFile_ << "[" << getCurrentDateTime() << "] "
                      << "[" << getLevelString(level) << "] "
                      << message << std::endl;
            dbLogFile_.flush();
        }
    }
}

// 服务端日志接口
void MyLogger::serverInfo(const std::string& message) {
    writeLog(LogType::SERVER, LogLevel::INFO, message);
}

void MyLogger::serverWarn(const std::string& message) {
    writeLog(LogType::SERVER, LogLevel::WARN, message);
}

void MyLogger::serverError(const std::string& message) {
    writeLog(LogType::SERVER, LogLevel::ERROR, message);
}

// 数据库日志接口
void MyLogger::dbInfo(const std::string& message) {
    writeLog(LogType::DATABASE, LogLevel::INFO, message);
}

void MyLogger::dbWarn(const std::string& message) {
    writeLog(LogType::DATABASE, LogLevel::WARN, message);
}

void MyLogger::dbError(const std::string& message) {
    writeLog(LogType::DATABASE, LogLevel::ERROR, message);
}

// 通用日志接口
void MyLogger::log(LogType type, LogLevel level, const std::string& message) {
    writeLog(type, level, message);
}
